/*
 * OpenCL clGetPlatformInfo() API Test
 * OpenCLでのプラットフォーム情報の取得サンプル
 *
 *参考：http://colorlessfeless.wordpress.com/2010/04/21/openclの基礎-–-clgetplatforminfoの使い方/
 */
#include <stdio.h>
#include <stdlib.h>
#include <OpenCL/opencl.h>
//#include <CL/opencl.h> //Windowsの人はこちら

/*
 - プラットフォーム数をnumPlatformsに設定します。
 - プラットフォームIDを取得します。
*/
static cl_platform_id* GetPlatformIDs(cl_uint* numPlatforms)
{
    cl_platform_id* ret = NULL;
	//プラットフォームの数を取得 (clGetPlatformIDsの使い方その１)
    cl_int result = clGetPlatformIDs(0, NULL, numPlatforms);
    if (result == CL_SUCCESS) {
        size_t allocateSize = sizeof(cl_platform_id) * (*numPlatforms);
        ret = reinterpret_cast<cl_platform_id*>(malloc(allocateSize));
        if (ret != NULL) {
			//プラットフォームIDを取得
            result = clGetPlatformIDs(*numPlatforms, ret, NULL);
            if (result != CL_SUCCESS) {
                free(ret);
                ret = NULL;
            }
        }
    }
    return ret;
}

/* 
 * プラットフォームに関する情報を出力します。
 * @param cl_platform_id プラットフォームID
 * @param name パラメータ情報の表示名
 * @param param パラメータ情報の種類を表す定数
 */
static void PrintPlatformInfoLine(cl_platform_id id, const char* name, cl_platform_info param)
{
    size_t length;
    cl_int ret;

	//buffサイズが毎回違うので、事前にclGetPlatformInfoを呼んでlengthを調べておく
    ret = clGetPlatformInfo(id, param, 0, NULL, &length);
    if (ret == CL_SUCCESS) {
		//領域確保
        char* buff = reinterpret_cast<char*>(malloc(length));
        if (buff != NULL) {
			//もう一度取り直す
            ret = clGetPlatformInfo(id, param, length, buff, NULL);
			//出力
            if (ret == CL_SUCCESS) {
                printf("%24s : %s\n", name, buff);
            } else {
                printf("%24s : NOT SUPPORTED\n", name);
            }
            free(buff);
        }
    }
}

/* プラットフォームの情報を全て表示します。
*/
static void PrintPlatformInfo(cl_platform_id id)
{
    PrintPlatformInfoLine(id, "CL_PLATFORM_PROFILE",    CL_PLATFORM_PROFILE);
    PrintPlatformInfoLine(id, "CL_PLATFORM_VERSOIN",    CL_PLATFORM_VERSION);
    PrintPlatformInfoLine(id, "CL_PLATFORM_NAME",       CL_PLATFORM_NAME);
    PrintPlatformInfoLine(id, "CL_PLATFORM_VENDOR",     CL_PLATFORM_VENDOR);
    PrintPlatformInfoLine(id, "CL_PLATFORM_EXTENSIONS", CL_PLATFORM_EXTENSIONS);
}

int main(void)
{
    cl_uint numPlatforms;
	//プラッフォームIDを取得しつつ、プラットフォーム数を設定
    cl_platform_id* ids = GetPlatformIDs(&numPlatforms);
    if (ids != NULL) {
        cl_uint i;
        for (i = 0; i < numPlatforms; i++) {
            printf("Platform %d : \n", i);
            PrintPlatformInfo(ids[i]);
        }
    } else {
        printf("There is no platforms.\n");
    }

	return 0;
}
